﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ModeloGaleriaNET;
using SeguridadGaleria.RoleManager;

namespace SeguridadGaleria
{
    public class ManejadorRoles
    {
        private RoleManagerService managerRoles;
        private readonly string nombre = "galeriaNET";
        private readonly char[] separador = new char[] { ';' };
        private jUDDIRoles uddiRoles;

        private ManejadorRoles()
        {
            managerRoles = new RoleManagerService();
            managerRoles.Timeout = 1000 * (int)ModeloGaleriaNET.Properties.Settings.Default.TimeOut;
            uddiRoles = jUDDIRoles.Instance;
        }

        public static readonly ManejadorRoles Instance = new ManejadorRoles();

        public GrupoValue GetGrupo(string grupo)
        {
            List<GrupoValue> grupos;

            grupos = GetGrupos();
            if (grupos == null || grupos.Count == 0)
                return null;
            grupos = grupos.Where(g => g.Nombre.Equals(grupo)).ToList();
            if (grupos == null || grupos.Count == 0)
                return null;
            return grupos.First();
        }

        public List<GrupoValue> GetGrupos()
        {
            string[] grupos;
            List<GrupoValue> salida;
            GrupoValue v;
            string[] perm;

            try
            {
                grupos = managerRoles.getGroupList(nombre, Utilities.EncriptarMD5(nombre), nombre).Split(separador);
                grupos = grupos.Where(g => string.IsNullOrWhiteSpace(g) == false).ToArray();
                salida = new List<GrupoValue>();
                foreach (string g in grupos)
                {
                    v = new GrupoValue();
                    v.Nombre = g;
                    perm = managerRoles.getGroupRoles(nombre, Utilities.EncriptarMD5(nombre), g, nombre).Split(separador).
                        Where(p => string.IsNullOrWhiteSpace(p) == false).Distinct().ToArray();
                    v.Permisos = perm;
                    salida.Add(v);
                }
                return salida;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        grupos = managerRoles.getGroupList(nombre, Utilities.EncriptarMD5(nombre), nombre).Split(separador);
                        grupos = grupos.Where(g => string.IsNullOrWhiteSpace(g) == false).ToArray();
                        salida = new List<GrupoValue>();
                        foreach (string g in grupos)
                        {
                            v = new GrupoValue();
                            v.Nombre = g;
                            perm = managerRoles.getGroupRoles(nombre, Utilities.EncriptarMD5(nombre), g, nombre).Split(separador).
                                Where(p => string.IsNullOrWhiteSpace(p) == false).Distinct().ToArray();
                            v.Permisos = perm;
                            salida.Add(v);
                        }
                        return salida;
                    }
                    catch (Exception)
                    {
                        return null;
                    }
                }
                return null;
            }
        }

        public List<string> GetAllPermisos()
        {
            List<string> salida;

            try
            {
                salida = managerRoles.getRoleList(nombre, Utilities.EncriptarMD5(nombre), nombre).Split(separador).
                    Where(p => string.IsNullOrWhiteSpace(p) == false).Distinct().ToList();
                return salida;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        salida = managerRoles.getRoleList(nombre, Utilities.EncriptarMD5(nombre), nombre).Split(separador).
                        Where(p => string.IsNullOrWhiteSpace(p) == false).Distinct().ToList();
                        return salida;
                    }
                    catch (Exception)
                    {
                        return null;
                    }
                }
                return null;
            }
        }

        public List<string> GetNombresGrupos()
        {
            List<GrupoValue> gruposValues;

            gruposValues = GetGrupos();

            if (gruposValues != null)
                return gruposValues.Select(gv => gv.Nombre.Replace(" ", string.Empty)).Distinct().ToList();
            else
                return null;
        }

        public bool CrearGrupo(GrupoValue grupo)
        {
            try
            {
                managerRoles.createGroup(nombre, Utilities.EncriptarMD5(nombre), grupo.Nombre, nombre);
                managerRoles.addRolesToGroup(nombre, Utilities.EncriptarMD5(nombre), grupo.Nombre, nombre, Utilities.ArrayToString(grupo.Permisos, ";"));
                return true;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        managerRoles.createGroup(nombre, Utilities.EncriptarMD5(nombre), grupo.Nombre, nombre);
                        managerRoles.addRolesToGroup(nombre, Utilities.EncriptarMD5(nombre), grupo.Nombre, nombre, Utilities.ArrayToString(grupo.Permisos, ";"));
                        return true;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                return false;
            }
        }

        public GrupoValue GetGrupoUsuario(string user)
        {
            GrupoValue salida;
            string[] roles;

            try
            {
                salida = new GrupoValue();
                salida.Nombre = managerRoles.getUserGroup(nombre, Utilities.EncriptarMD5(nombre), user, nombre);
                salida.Permisos = managerRoles.getGroupRoles(nombre, Utilities.EncriptarMD5(nombre), salida.Nombre, nombre).Split(separador).
                        Where(p => string.IsNullOrWhiteSpace(p) == false).Distinct().ToArray();
                roles = managerRoles.getUserRoles(nombre, Utilities.EncriptarMD5(nombre), user, nombre).Split(separador).
                    Where(p => string.IsNullOrWhiteSpace(p) == false).Distinct().ToArray();
                salida.PermisosNuevos = roles.Except(salida.Permisos).ToArray();
                salida.PermisosBorrados = salida.Permisos.Except(roles).ToArray();
                return salida;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        salida = new GrupoValue();
                        salida.Nombre = managerRoles.getUserGroup(nombre, Utilities.EncriptarMD5(nombre), user, nombre);
                        salida.Permisos = managerRoles.getGroupRoles(nombre, Utilities.EncriptarMD5(nombre), salida.Nombre, nombre).Split(separador).
                                Where(p => string.IsNullOrWhiteSpace(p) == false).Distinct().ToArray();
                        roles = managerRoles.getUserRoles(nombre, Utilities.EncriptarMD5(nombre), user, nombre).Split(separador).
                            Where(p => string.IsNullOrWhiteSpace(p) == false).Distinct().ToArray();
                        salida.PermisosNuevos = roles.Except(salida.Permisos).ToArray();
                        salida.PermisosBorrados = salida.Permisos.Except(roles).ToArray();
                        return salida;
                    }
                    catch (Exception)
                    {
                        return null;
                    }
                }
                return null;
            }
        }

        public bool ActualizarPermisosGrupo(GrupoValue grupo)
        {
            string roles;

            try
            {
                if (grupo.PermisosBorrados != null && grupo.PermisosBorrados.Length > 0)
                {
                    roles = Utilities.ArrayToString(grupo.PermisosBorrados, ";");
                    managerRoles.deleteRolesFromGroup(nombre, Utilities.EncriptarMD5(nombre), grupo.Nombre, nombre, roles);
                }
                if (grupo.PermisosNuevos != null && grupo.PermisosNuevos.Length > 0)
                {
                    roles = Utilities.ArrayToString(grupo.PermisosNuevos, ";");
                    managerRoles.addRolesToGroup(nombre, Utilities.EncriptarMD5(nombre), grupo.Nombre, nombre, roles);
                }
                return true;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        if (grupo.PermisosBorrados != null && grupo.PermisosBorrados.Length > 0)
                        {
                            roles = Utilities.ArrayToString(grupo.PermisosBorrados, ";");
                            managerRoles.deleteRolesFromGroup(nombre, Utilities.EncriptarMD5(nombre), grupo.Nombre, nombre, roles);
                        }
                        if (grupo.PermisosNuevos != null && grupo.PermisosNuevos.Length > 0)
                        {
                            roles = Utilities.ArrayToString(grupo.PermisosNuevos, ";");
                            managerRoles.addRolesToGroup(nombre, Utilities.EncriptarMD5(nombre), grupo.Nombre, nombre, roles);
                        }
                        return true;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                return false;
            }
        }

        public bool ActualizarPermisosGrupo(List<GrupoValue> grupos)
        {
            bool salida = true;
            foreach (GrupoValue g in grupos)
                salida = salida && ActualizarPermisosGrupo(g);

            return salida;
        }

        public bool? CanUse(string permiso, string user)
        {
            try
            {
                return managerRoles.canUse(nombre, Utilities.EncriptarMD5(nombre), user, nombre, permiso);
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        return managerRoles.canUse(nombre, Utilities.EncriptarMD5(nombre), user, nombre, permiso);
                    }
                    catch (Exception)
                    {
                        return null;
                    }
                }
                return null;
            }
        }

        public bool? CanUseApplication(string permiso)
        {
            try
            {
                return managerRoles.canUse(nombre, Utilities.EncriptarMD5(nombre), nombre, "ecommerce", permiso);
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        return managerRoles.canUse(nombre, Utilities.EncriptarMD5(nombre), nombre, "ecommerce", permiso);
                    }
                    catch (Exception)
                    {
                        return null;
                    }
                }
                return null;
            }
        }

        public bool CambiarGrupo(string user, string grupo)
        {
            try
            {
                managerRoles.setGroup(nombre, Utilities.EncriptarMD5(nombre), user, nombre, grupo, nombre);
                return true;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        managerRoles.setGroup(nombre, Utilities.EncriptarMD5(nombre), user, nombre, grupo, nombre);
                        return true;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                return false;
            }
        }

        public bool AddPermisosUsuario(string[] permisos, string user)
        {
            string perm;

            try
            {
                perm = Utilities.ArrayToString(permisos, ";");
                managerRoles.addRolesToUser(nombre, Utilities.EncriptarMD5(nombre), user, nombre, perm);
                return true;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        perm = Utilities.ArrayToString(permisos, ";");
                        managerRoles.addRolesToUser(nombre, Utilities.EncriptarMD5(nombre), user, nombre, perm);
                        return true;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                return false;
            }
        }

        public bool DeletePermisosUsuario(string[] permisos, string user)
        {
            try
            {
                managerRoles.deleteRolesFromUser(nombre, Utilities.EncriptarMD5(nombre), user, nombre, Utilities.ArrayToString(permisos, ";"));
                return true;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        managerRoles.deleteRolesFromUser(nombre, Utilities.EncriptarMD5(nombre), user, nombre, Utilities.ArrayToString(permisos, ";"));
                        return true;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                return false;
            }
        }

        public bool CreateUser(string user, string group)
        {
            try
            {
                managerRoles.createUser(nombre, Utilities.EncriptarMD5(nombre), user, nombre);
                managerRoles.setGroup(nombre, Utilities.EncriptarMD5(nombre), user, nombre, group, nombre);
                return true;
            }
            catch (Exception)
            {
                if (uddiRoles.UpdateURLRoles())
                {
                    try
                    {
                        managerRoles.createUser(nombre, Utilities.EncriptarMD5(nombre), user, nombre);
                        managerRoles.setGroup(nombre, Utilities.EncriptarMD5(nombre), user, nombre, group, nombre);
                        return true;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                return false;
            }
        }
    }
}
